import json

from django.db import transaction
from django.db.models import Q
from rest_framework.filters import OrderingFilter
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet

from apps.club_system.club.filters import ClubFilter
from apps.club_system.club.models import Club, ClubMember, ClubCheck, Log
from apps.club_system.club.serializers.club import ClubBaseSerializer, ClubPlusSerializer, ClubSerializer, \
    ClubFirstCheckSerialzier, \
    ClubSecondCheckSerializer, ClubMemberSerializer, CLubListSerializer, ClubNameListSerializer
from apps.club_system.club.serializers.club_type import ClubTypeListserializer
from apps.common.account.models import Account
from utils.common import Pagination


class ClubViewSet(ModelViewSet):
    filter_backends = (OrderingFilter, DjangoFilterBackend)
    queryset = Club.objects.select_related('account', 'business_unit', 'type')
    filter_class = ClubFilter
    pagination_class = Pagination
    ordering_fields = ('id', 'created_time')

    # list、retrieve 用的 ClubBaseSerializer
    def get_serializer_class(self):
        if self.action in ['partial_update', 'create']:
            return ClubSerializer
        elif self.action == 'list':
            return CLubListSerializer
        else:
            return ClubBaseSerializer

    def list(self, request, *args, **kwargs):
        """ 获取已经通过的社团 """

        queryset = self.get_queryset().filter(first_check_status='通过', second_check_status='通过', is_active=True)
        queryset = self.filter_queryset(queryset)
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = CLubListSerializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = CLubListSerializer(queryset, many=True)
        return Response(serializer.data)

    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = self.get_serializer(instance, context={'request': request})
        return Response(serializer.data)

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        if instance.first_check_status == '通过' or instance.second_check_status == '通过':
            return Response({'message': '已通过的数据无法删除'}, status=status.HTTP_400_BAD_REQUEST)
        if instance.account != request.user:
            return Response({'message': '只有该社团的创建者才能删除社团！'}, status=status.HTTP_400_BAD_REQUEST)
        ids = ClubMember.objects.filter(club=instance, is_active=True).values_list('id', flat=True)
        tmp = [ClubMember(id=i, is_active=False) for i in list(ids)]
        ClubMember.objects.bulk_update(tmp, fields=['is_active'])
        instance.is_active = False
        instance.save()
        Log.objects.create(username=request.user.username, name=request.user.realname, operate_type=3,
                           table_name='Club', comment=f'删除了社团名字为{instance.name}的社团',
                           detail=f'删除了社团名字为{instance.name}的社团')
        return Response({'message': '删除成功'}, status=status.HTTP_204_NO_CONTENT)

    def create(self, request, *args, **kwargs):
        # 获取老师学号
        teacher_id = request.data.get('teacher_id', None)
        exists = ClubMember.objects.filter(account=request.user, role=3, is_active=True).exists()
        if exists:
            return Response({'message': '每人只能当一个社团的会长'}, status=status.HTTP_400_BAD_REQUEST)
        if not teacher_id:
            return Response({'message': '必须有老师的工号'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            with transaction.atomic():
                serializer = self.get_serializer(data=request.data)
                serializer.is_valid(raise_exception=True)
                serializer.save()
                account_id = serializer.data['account_id']
                club_id = serializer.data['id']
                ClubMember.objects.create(account_id=teacher_id, role=4, club_id=club_id, is_active=True)
                ClubMember.objects.create(account_id=account_id, role=3, club_id=club_id, is_active=True)
                Log.objects.create(username=request.user.username, name=request.user.realname, operate_type=1,
                                   table_name='Club', comment=f'创建了社团名字为{serializer.data["name"]}的社团',
                                   detail=str(request.data) if request.data else '')
        except Account.DoesNotExist:
            return Response({'message': '不存在该教师工号'}, status=status.HTTP_400_BAD_REQUEST)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def update(self, request, *args, **kwargs):
        teacher_id = request.data.get('teacher_id', '')
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        exists = ClubMember.objects.filter(club=instance, account=request.user, role=3, is_active=True).exists()
        if not exists:
            return Response({'message': '必须是该社团的会长才能修改！'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            with transaction.atomic():
                # 修改指导老师
                if teacher_id:
                    ClubMember.objects.filter(is_active=True, role=4, club_id=instance.id).update(account_id=teacher_id)
                serializer = self.get_serializer(instance, data=request.data, partial=partial)
                serializer.is_valid(raise_exception=True)
                self.perform_update(serializer)
                Log.objects.create(username=request.user.username, name=request.user.realname, operate_type=2,
                                   table_name='Club', comment=f'修改了社团名字为{serializer.data["name"]}的社团信息',
                                   detail=str(request.data) if request.data else '')
        except Exception as e:
            return Response({'message': e.args}, status=status.HTTP_400_BAD_REQUEST)
        if getattr(instance, '_prefetched_objects_cache', None):
            instance._prefetched_objects_cache = {}
        return Response(serializer.data)

    @action(methods=['get'], detail=False, url_path='first_check_list')
    def first_check_list(self, request, *args, **kwargs):
        """ 获取一级审核待审核数据 """
        if request.user.is_admin():
            queryset = Club.objects.select_related('account', 'business_unit', 'type') \
                .filter(first_check_status='待审核', second_check_status='待审核', is_active=True)
        else:
            account_id = request.user.id
            values = ClubMember.objects.filter(account_id=account_id, role=4).values_list('club_id', flat=True)
            queryset = Club.objects.select_related('account', 'business_unit', 'type') \
                .filter(id__in=list(values), first_check_status='待审核', second_check_status='待审核', is_active=True)
        queryset = self.filter_queryset(queryset)
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = ClubFirstCheckSerialzier(page, many=True, context={'request': request})
            return self.get_paginated_response(serializer.data)
        serializer = ClubFirstCheckSerialzier(queryset, many=True, context={'request': request})
        return Response(serializer.data)

    @action(methods=['get'], detail=False, url_path='second_check_list')
    def second_check_list(self, request, *args, **kwargs):
        """ 获取二级审核待审核数据，一级审核过后才可以进行二级审核"""
        queryset = Club.objects.select_related('business_unit', 'account', 'type') \
            .filter(first_check_status='通过', second_check_status='待审核', is_active=True)
        queryset = self.filter_queryset(queryset)
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = ClubSecondCheckSerializer(page, many=True, context={'request': request})
            return self.get_paginated_response(serializer.data)
        serializer = ClubSecondCheckSerializer(queryset, many=True, context={'request': request})
        return Response(serializer.data)

    @action(methods=['post'], detail=True, url_path='first_check')
    def first_check(self, request, pk=None):
        """ 一级审核 """
        check_status = request.data.get('check_status', '')
        check_opinion = request.data.get('check_opinion', '')
        if check_status not in ('通过', '不通过'):
            return Response({'message': '缺少审核状态或者审核状态错误'}, status=status.HTTP_400_BAD_REQUEST)

        if not request.user.is_admin() and not request.user.is_teacher_manager():
            return Response({'message': '您无权限进行审核！'}, status=status.HTTP_400_BAD_REQUEST)

        try:
            instance = Club.objects.only('id').get(id=pk)
        except Club.DoesNotExist:
            return Response({'message': '错误的参数'}, status=status.HTTP_400_BAD_REQUEST)
        ClubCheck.objects.create(club=instance, account=request.user, check_status=check_status,
                                 check_opinion=check_opinion, check_level=1)

        Log.objects.create(username=request.user.username, name=request.user.realname, operate_type=4,
                           table_name='Club', comment=f'审核了社团名字为{instance.name}的社团信息',
                           detail=f'审核状态为{check_status}, 审核意见为{check_opinion}, 为一级审核')

        # 每次审核后将一级审核状态改为最新的审核状态
        instance.first_check_status = check_status
        instance.save()
        return Response({'message': '审核成功'}, status=status.HTTP_200_OK)

    @action(methods=['post'], detail=True, url_path='second_check')
    def second_check(self, request, pk=None):
        """ 二级审核 """
        if not request.user.is_admin() and not request.user.is_role('club_school_manager'):
            return Response({'message': '您无权限进行审核！'}, status=status.HTTP_400_BAD_REQUEST)
        check_status = request.data.get('check_status', '')
        check_opinion = request.data.get('check_opinion', '')
        if check_status not in ('通过', '不通过'):
            return Response({'message': '缺少审核状态或者审核状态错误'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            instance = Club.objects.only('id').get(id=pk)
        except Club.DoesNotExist:
            return Response({'message': '错误的参数'}, status=status.HTTP_400_BAD_REQUEST)
        ClubCheck.objects.create(club=instance, account=request.user, check_status=check_status,
                                 check_opinion=check_opinion, check_level=2)

        Log.objects.create(username=request.user.username, name=request.user.realname, operate_type=4,
                           table_name='Club', comment=f'审核了社团名字为{instance.name}的社团信息',
                           detail=f'审核状态为{check_status}, 审核意见为{check_opinion}, 为二级审核')

        # 每次审核后将二级审核状态改为最新的审核状态
        instance.second_check_status = check_status
        instance.save()
        return Response({'message': '审核成功'}, status=status.HTTP_200_OK)

    # url: api/club/whole/
    @action(methods=['get'], detail=False, url_path='whole')
    def get_whole_club(self, request):
        # todo: 校团委看社团列表,包括审核中、注销、活跃
        queryset = Club.objects.all().order_by('id').select_related('account', 'business_unit', 'type')
        queryset = self.filter_queryset(queryset)
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = CLubListSerializer(page, many=True, context={'request': request})
            return self.get_paginated_response(serializer.data)
        serializer = CLubListSerializer(queryset, many=True, context={'request': request})
        return Response(serializer.data)

    # url: api/club/id/whole/
    @action(methods=['get'], detail=True, url_path='whole')
    def get_club(self, request, pk=None):
        # todo:从详情看或者校团委看社团详细情况、附带审核记录
        try:
            instance = Club.objects.only('id').get(id=pk)
        except Club.DoesNotExist:
            return Response({'message': '错误的参数'}, status=status.HTTP_400_BAD_REQUEST)
        serializer = ClubPlusSerializer(instance, many=False, context={'request': request})
        return Response(serializer.data)

    """ 获取社团成员 """
    @action(methods=['get'], detail=True, url_path='member')
    def get_active_students(self, request, pk=None):
        is_active = request.query_params.get('is_active', 1)
        queryset = ClubMember.objects.filter(club_id=pk, is_active=is_active).select_related('account')
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = ClubMemberSerializer(page, many=True, context={'request': request})
            return self.get_paginated_response(serializer.data)
        serializer = ClubMemberSerializer(queryset, many=True, context={'request': request})
        return Response(serializer.data)

    # url : api/club/myclub/
    """ 获取我的社团，校团委和管理员看到全部，其他看到自己的 """
    @action(methods=['get'], detail=False, url_path='myclub')
    def get_myclub(self, request):
        # --我加入的-- ｜ --我创建的-- 注销的不要
        queryset = self.filter_queryset(self.get_queryset())
        if request.user.is_admin() or request.user.is_role('club_school_manager'):  # 超级管理员或校团委看到全部
            queryset = queryset.filter(is_active=True)
        else:
            values = ClubMember.objects \
                .filter(account_id=request.user.id, is_active=True).values_list('club_id', flat=True)
            queryset = queryset.filter(is_active=True, id__in=list(values))
        page = self.paginate_queryset(queryset)
        if page is not None:
            # 传递 context={'request': request}可以返回绝对url
            serializer = ClubPlusSerializer(page, many=True, context={'request': request})
            return self.get_paginated_response(serializer.data)
        serializer = ClubPlusSerializer(queryset, many=True, context={'request': request})
        return Response(serializer.data)

    @action(methods=['post'], detail=False, url_path='application_time')
    def change_application_time(self, request, pk=None):
        if not request.user.is_admin() and not request.user.is_role('club_school_manager'):
            return Response({'message': '您无权限进行设置！'}, status=status.HTTP_400_BAD_REQUEST)
        apply_start_time = request.data.get('apply_start_time', '')
        apply_end_time = request.data.get('apply_end_time', '')
        values = request.data.get('values', [])
        print(values)
        if not all([apply_start_time, apply_end_time]):
            return Response({'message': '缺少必填字段'})
        if apply_start_time >= apply_end_time:
            return Response({'message': '报名结束时间不能早于报名开始时间'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            tmp = [Club(id=i, apply_start_time=apply_start_time, apply_end_time=apply_end_time) for i in
                   list(set(values))]
            Club.objects.bulk_update(tmp, fields=['apply_start_time', 'apply_end_time'])

            club_name_list = Club.objects.filter(id__in=list(set(values))).values_list('name', flat=True)

            Log.objects.create(username=request.user.username, name=request.user.realname, operate_type=2,
                               table_name='Club', comment=f'设置社团的招新时间',
                               detail=f'设置的社团有{club_name_list}，开始时间为：{apply_start_time}, 结束时间为：{apply_end_time}')

        except Exception as e:
            print(e.args)
            return Response({'message': '日期格式为 YYYY-MM-DD HH:MM:SS'}, status=status.HTTP_400_BAD_REQUEST)
        return Response({'message': '社团招新时间设置成功'})

    @action(methods=['get'], detail=False, url_path='selected/president_club')
    def get_president_club(self, request):
        # 前提会长和社团是一对一关系
        obj = ClubMember.objects.filter(account_id=request.user.id, is_active=True, role=3).first()
        club = Club.objects.filter(id=obj.club_id).first()
        return Response({'account_id': request.user.id, 'club_id': club.id, 'club_name': club.name})

    @action(methods=['get'], detail=False, url_path='selected/club_name')
    def get_club_name(self, request):
        # 社团名字下拉宽框
        queryset = self.queryset.filter(is_active=True, first_check_status='通过', second_check_status='通过')
        serializer = ClubNameListSerializer(queryset, many=True)
        return Response(serializer.data)

    @action(methods=['post'], detail=True, url_path='change_teacher')
    def change_teacher(self, request, pk=None):
        if not request.user.is_admin() and not request.user.is_role('club_school_manager'):
            return Response({'message': '您无权限进行更换指导老师！'}, status=status.HTTP_400_BAD_REQUEST)
        teacher_id = request.data.get('teacher_id', '')
        if not all([teacher_id]):
            return Response({'message': '缺少参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            instance = Account.objects.only('id').get(id=teacher_id)
        except Account.DoesNotExist:
            return Response({'message': '不存在该账号'}, status=status.HTTP_400_BAD_REQUEST)
        ClubMember.objects.filter(is_active=True, role=4, club_id=pk).update(account_id=teacher_id)
        club = Club.objects.only('id').get(id=pk)
        Log.objects.create(username=request.user.username, name=request.user.realname, operate_type=2,
                           table_name='ClubMember', comment=f'更换了社团名为{club.name}的指导老师',
                           detail=f'将该社团的指导老师更换为工号：{instance.username}, 名字：{instance.realname}的老师')
        return Response({'message': '指导老师更换成功'}, status=status.HTTP_200_OK)

    """ 根据权限获取社团名 """
    @action(methods=['get'], detail=False, url_path='perm_club')
    def get_perm_club(self, request):
        queryset = self.filter_queryset(self.get_queryset())
        if request.user.is_admin() or request.user.is_role('club_school_manager'):  # 超级管理员或校团委看到全部
            queryset = queryset.filter(is_active=True)
        else:
            values = ClubMember.objects \
                .filter(account_id=request.user.id, is_active=True).values_list('club_id', flat=True)
            queryset = queryset.filter(is_active=True, id__in=list(values))

        res_data = queryset.values('id', 'name')
        return Response({'data': res_data, 'message': '获取成功'}, status=status.HTTP_200_OK)
